package org.tgcloud.group.core.WXUtils.alipay.request;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tgcloud.group.core.StringUtil;
import org.tgcloud.group.core.WXUtils.alipay.AlipayConfig;
import org.tgcloud.group.core.WXUtils.alipay.AlipayCore;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by cloudLiu on 2015/8/25.
 * 支付宝网页支付请求数据
 */
public class WebPayRequest{

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    /*
    * 接口名称
    * String
    * 接口名称。固定值。 web_app支付：alipay.wap.create.direct.pay.by.user
    * 不可空
    */
    private String service;

    /*
    合作者身份 ID
    String(16)
    签约的支付宝账号对应的支付宝唯一用户号。以 2088 开头的 16 位纯数字组成。
    不可空
    */
    private String partner;

    /*
    参数编码字符集
    String
    商户网站使用的编码格式，固 定为 utf-8。
    不可空
    */
    private String _input_charset;

    /*
    * 签名方式
    * String
    * 签名类型，目前仅支持 RSA。
    * 不可空
    */
    private String sign_type;

    /*
    * 签名
    * String
    * 签名详见sign方法
    * 不可空
    */
    private String sign;

    /*
    * 页面跳转同步通知页面路径
    * String(200)
    * 支付宝处理完请求后，当前页面自动跳转到商户网站里指定页面的 http 路径。
    * 可空
    */
    private String return_url;

    /*
    * 服务器异步通知页面路径
    * String(200)
    * 支付宝服务器主动通知商户网站里指定的页面 http 路径。
    * 可空
    */
    private String notify_url;


    /*
    商户网站唯一订单号
    String(64)
    支付宝合作商户网站唯一订单号。
    不可空
    */
    private String out_trade_no;

    /*
    商品名称
    String(128)
    商品的标题/交易标题/订单标题/订单关键字等。该参数最长为 128 个汉字。
    不可空
    */
    private String subject;

    /*
    总金额
    Number
    该笔订单的资金总额，单位为RMB-Yuan。取值范围为[0.01， 100000000.00]，精确到小数点后两位。
    不可空
    */
    private String total_fee;

    /*
   卖家支付宝账号
   String(16)
   卖家支付宝账号（邮箱或手机号码格式）或其对应的支付宝唯一用户号（以 2088 开头的纯 16 位数字）。
   不可空
   */
    private String seller_id;

    /*
    * 支付类型
    * String(4 )
    * 支付类型。默认值为： 1（商品购买）。
    * 不可空
    */
    private String payment_type;

    /*
    商品详情
    String(1000)
    对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给 body。
    可空*/
    private String body;

    /*
    商品展示网址
    String(400)
    收银台页面上，商品展示的超链接。
    可空*/
    private String show_url;

    /*
    未付款交易的超时时间
    String
    设置未付款交易的超时时间，一旦超时，该笔交易就会自动被关闭。当用户输入支付密码、点击确认付款后（即创建支付宝交易后）开始计时。取值范围： 1m～15d，或者使用绝对时间（示例格式：2014-06-13 16:00:00）。
    m-分钟， h-小时， d-天， 1c-当天（无论交易何时创建，都在 0 点关闭）。该参数数值不接受小数点，如1.5h，可转换为 90m。
    当用户输入支付密码、点击确认付款后（即创建支付宝交易后）开始计时。
    可空
    * */
    private String it_b_pay;

    /*
    钱包token
    String
    接入极简版 wap 收银台时支持。当商户请求是来自支付宝钱包，在支付宝钱包登录后，有生成登录信息 token 时，使用该参数传入 token 将可以实现信任登录收银台，不需要再次登录。
    可空
    */
    private String extern_token;

    /*
    航旅订单其它费用
    Number
    航旅订单中除去票面价之外的费用，单位为 RMB-Yuan。取值范围为[0.01,100000000.00]，精确到小数点后两位。
    可空*/
    private String otherfee;

    /*
    航旅订单金额
    String(1,64)
    航旅订单金额描述，由四项或两项构成，各项之间由“ |”分隔，每项包含金额与描述，金额与描述间用“ ^”分隔，票面价之外的价格之和必须与 otherfee 相等。
    可空*/
    private String airticket;

    /**
     * 初始化网站付费请求
     * @param subject
     * @param total_fee
     */
    public WebPayRequest(String subject, String total_fee)
    {
        this(subject,total_fee,null);
    }

    public WebPayRequest(String subject, String total_fee, String body)
    {
        this(subject,total_fee,body,null);
    }

    public WebPayRequest(String subject, String total_fee, String body, String show_url) {

        this(subject,total_fee,body,show_url,null,null,null);
    }

    public WebPayRequest(String subject, String total_fee, String body, String show_url, String extern_token, String otherfee, String airticket)
    {
        this.extern_token = extern_token;
        this.otherfee = otherfee;
        try {
            this.airticket = airticket==null?airticket: URLEncoder.encode(airticket,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        this.subject = subject;
        this._input_charset = AlipayConfig.input_charset;
        this.seller_id = AlipayConfig.seller_id;
        this.partner = AlipayConfig.partner;
        this.it_b_pay = AlipayConfig.it_b_pay;
        this.service = AlipayConfig.ali_web_service;
        this.payment_type = AlipayConfig.payment_type_1;
        this.notify_url = AlipayConfig.notify_url;
        this.return_url = AlipayConfig.return_url;
        this.show_url = show_url;
        /*订单号生成，保证唯一就行*/
        StringBuilder sRand = new StringBuilder(15);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String str = sdf.format(date);
        sRand.append(str);
        for (int i = 0; i < 10; i++) {
            // 取得一个随机数字
            String tmp = StringUtil.getRandomInt() + "";
            sRand.append(tmp);
        }
        this.out_trade_no = sRand.toString();
        this.total_fee = total_fee;
        this.body = body;
    }

    /**
     * 获取非空的参数map
     * @return
     */
    private Map<String,String> getParams()
    {
        Map<String, String> sParaTemp = new HashMap<String, String>();
        sParaTemp.put("service", this.service);
        sParaTemp.put("partner", this.partner);
        sParaTemp.put("seller_id", this.seller_id);
        sParaTemp.put("_input_charset", this._input_charset);
        sParaTemp.put("payment_type", this.payment_type);
        sParaTemp.put("notify_url", this.notify_url);
        sParaTemp.put("return_url",this.return_url);
        sParaTemp.put("show_url",this.show_url);
        sParaTemp.put("out_trade_no", this.out_trade_no);
        sParaTemp.put("subject", this.subject);
        sParaTemp.put("total_fee", this.total_fee);
        sParaTemp.put("body", this.body);
        sParaTemp.put("it_b_pay", this.it_b_pay);
        sParaTemp.put("extern_token",this.extern_token);
        sParaTemp.put("otherfee",this.otherfee);
        sParaTemp.put("airticket",this.airticket);
        sParaTemp.put("sign",this.sign);
        sParaTemp.put("sign_type",this.sign_type);
        return sParaTemp;
    }

    /**
     * 获取返回给手机端的响应
     * @return
     */
    public String getTelResponse() {

        //除去数组中的空值和签名参数
        Map<String, String> sPara = AlipayCore.paraFilter(getParams());
        //生成签名结果
        String mySign = AlipayCore.buildRequestMySignNoYinHao(sPara);

        //签名结果与签名方式加入请求提交参数组中
        try {
            sPara.put("sign", URLEncoder.encode(mySign, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            logger.warn("encode出错 - WebPayRequest");
            e.printStackTrace();
        }
        sPara.put("sign_type", AlipayConfig.sign_type);
        StringBuilder sb = new StringBuilder();
        List<String> keys_ = Lists.newArrayList();
        for (String key : sPara.keySet())
        {
            keys_.add(key);
        }
        Collections.sort(keys_);
        for (String key : keys_)
        {
            sb.append(key + "=" + sPara.get(key) + "&");
        }
        sb.deleteCharAt(sb.lastIndexOf("&"));
        return AlipayConfig.ALI_PAY_GATEWAY + sb.toString();
    }

}
